package com.zxt.content.user.service.impl;

import com.zxt.bean.LoginUserInfoApiVO;
import com.zxt.enums.CommonStatusEnum;
import com.zxt.user.resp.LoginUserVO;
import com.zxt.bean.ServiceException;
import com.zxt.bean.ResultCode;
import com.zxt.bean.UserInfoVO;
import com.zxt.utils.ServletUtil;
import com.zxt.utils.ZXTBeanUtils;
import com.zxt.content.user.req.LoginBodyDTO;
import com.zxt.content.user.manager.BUserManager;
import com.zxt.content.user.model.BUser;
import com.zxt.user.security.service.TokenService;
import com.zxt.content.user.service.BUserService;
import com.zxt.content.user.resp.BUserVO;
import lombok.AllArgsConstructor;
import org.springframework.security.authentication.*;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

/**
 * user模块业务逻辑层
 *
 * @author zxt
 */
@Service(value = "bUserService")
@AllArgsConstructor
public class BUserServiceImpl implements BUserService {

    private final BUserManager bUserManager;
    private final AuthenticationManager authenticationManager;
    private final TokenService tokenService;

    @Override
    public List<BUserVO> query() {
        return ZXTBeanUtils.beanCopy(bUserManager.list(), BUserVO.class);
    }

    @Override
    public String login(LoginBodyDTO dto) {
        // 用户验证
        Authentication authentication = null;
        try {
            // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
            authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(dto.getUsername(), dto.getPassword()));
        } catch (Exception e) {
            if (e instanceof InternalAuthenticationServiceException) {
                throw new ServiceException(ResultCode.LOGIN_ERROR);
            } else if (e instanceof BadCredentialsException) {
                throw new ServiceException(ResultCode.USER_PWD_ERROR);
            } else if (e instanceof DisabledException) {
                throw new ServiceException(ResultCode.USER_DISABLE_ERROR);
            } else {
                ServiceException exception = (ServiceException) e;
                throw new ServiceException(exception.getCode(), exception.getMessage());
            }
        }
        // AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
        LoginUserVO loginUser = (LoginUserVO) authentication.getPrincipal();
        LoginUserInfoApiVO loginUserInfo = ZXTBeanUtils.beanCopy(loginUser, LoginUserInfoApiVO.class);
        loginUserInfo.setIsAdmin(loginUser.getUser().getIsAdmin());
        loginUserInfo.setUser(ZXTBeanUtils.beanCopy(loginUser.getUser(), UserInfoVO.class));
        // 生成token加入认证框架，并且保存认证的Token保存到redis
        String token = tokenService.createToken(loginUserInfo);
        //设置最后登录时间和最后登录ip地址
        HttpServletRequest request = ServletUtil.getRequest();
        BUser bUser = new BUser();
        bUser.setUserName(dto.getUsername());
        bUser.setLoginIp(request.getRemoteAddr());
        bUser.setLoginDate(LocalDateTime.now());
        bUserManager.updateLoginByUserName(bUser);
        return token;
    }

    @Override
    public void register(LoginBodyDTO dto) {
        BUser byUserName = bUserManager.getByUserName(dto.getUsername());
        if (Objects.nonNull(byUserName)) {
            throw new ServiceException(ResultCode.COMMON_MESSAGE, "该用户名称已经存在");
        }

        BUser bUser = new BUser();
        bUser.setUserName(dto.getUsername());
        bUser.setNickName(dto.getUsername());
        bUser.setUserPwd(dto.getPassword());
        bUser.setIsAdmin(Boolean.FALSE);
        bUser.setCommonStatus(CommonStatusEnum.ENABLE.getValue());
        bUser.setRemark("合法创建管理用户");
        bUserManager.createUser(bUser);
    }

}
